#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/CompilerOutputter.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/TextTestProgressListener.h>

#include "Fake.h"

class IPerson
{
public:
    virtual void doSomething() = 0;
    virtual int returnSomething() = 0;
};

//template<int I>
//class CheckIdx
//{
//public:
//    int __thiscall funcThisCall()
//    {
//        return I; 
//    }
//};
//
//template<int I>
//static void* getIndexFuncRecur(int i)
//{
//    if (i == I) {
//        auto ptr = &CheckIdx<I>::funcThisCall;
//        return *((void**) &ptr);
//    } else {
//        return getIndexFuncRecur<I+1>(i);
//    }
//}
//
//template<>
//void* getIndexFuncRecur<50>(int i)
//{
//    return 0;
//}
//
//class Check 
//{
//public:
//    static bool m_isCheckCall;
//    static size_t m_destructorOffset;
//
//    typedef bool* CheckType;        
//};
//
//typedef int (__thiscall Check::*CheckFuncPtrThisCall) ();
//
//template<typename T>
//void everyCall(T method)
//{
//    void* vtable[50];
//    for (int i = 0; i < 50; i++) {
//        vtable[i] = getIndexFuncRecur<0>(i);
//    }
//
//    void* vtbl = &vtable[0];
//
//    Check* checkObject = (Check*) &vtbl;
//
//    CheckFuncPtrThisCall check = reinterpret_cast<CheckFuncPtrThisCall>(method);
//
//    int offset = (checkObject->*check)();
//
//    int i = 0;
//}

class FaqeTester
{
public:
    FaqeTester()
        :
        _testOutputter(&_testResultCollector, std::cerr)
    {
        _testResult.addListener(&_testResultCollector);
        _testResult.addListener(&_testProgressListener);

        _testRunner.addTest(CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest());
    }

    bool run()
    {
        std::cout << "Running";

        _testRunner.run(_testResult);
        _testOutputter.write();

        return _testResultCollector.wasSuccessful();
    }

private:
    CPPUNIT_NS::TestResult               _testResult;
    CPPUNIT_NS::TestResultCollector      _testResultCollector;
    CPPUNIT_NS::TextTestProgressListener _testProgressListener;
    CPPUNIT_NS::TestRunner               _testRunner;
    CPPUNIT_NS::CompilerOutputter        _testOutputter;
};

int main()
{
    FaqeTester tester;
    return tester.run() ? 0 : 1;
}
